Editor.Property = function () {
	var resource;
	var uuidIni;
	var uuidEnd;
	var figIni;
	var figEnd;
	var figArrowPoint;
	var impl;

	return {
		init: function (u, ui, ue) {
			resource = new Editor.Resource();
			resource.init(u,this);
			uuidIni = ui;
			uuidEnd = ue;
			Editor.STATE.SHAPES.get(uuidIni).addInProperties(u);
			Editor.STATE.SHAPES.get(uuidEnd).addInProperties(u);
			impl = this;
		},
    getTypeClass: function () {
      return "property";
    },
		getInfo: function () {
			var str = '';
			if (Editor.CONFIG.DEBUG) {
				str = 'Property:\n';
				str += 'uuidIni: ' + uuidIni + '\n';
				str += 'uuidEnd: ' + uuidEnd + '\n';
				str += '\n';
			}
			str += resource.getInfo();
			return str;
		},
		getNamespace: function () {
			return resource.getNamespace();
		},
		setNamespace: function (n) {
			resource.setNamespace(n);
		},
		getName: function () {
			return resource.getName();
		},
		setName: function (n) {
			resource.setName(n);
		},
		getText: function () {
			var t = resource.getText();
			return t;
		},
		_remove: function () {
			resource._remove();
			this.removeLines();
		},
		remove: function () {
      var cmd = new JS.Command({
        execute: function () {
					resource.remove();
					impl.removeLines();
        },
        undo: function () {
          impl.draw();
        },
        stack: Editor.STATE.CMDSTACK
      });
      cmd.name = 'remove property';
      cmd.execute();
		},
		draw: function () {
			resource.draw();
			this.drawLines(true);
			this.toFront();
		},
		removeLines: function () {
			figIni.remove();
			delete figIni;
			figEnd.remove();
			delete figEnd;
			figArrowPoint.remove();
			delete figArrowPoint;
		},
		drawLines: function (init) {
			var isInit = false;
			if (init) {
				isInit = true;
			} 
			var shapes = Editor.STATE.SHAPES;
			var ini = shapes.get(uuidIni);
			var end = shapes.get(uuidEnd);
			
			var px = resource.getX()+resource.getWidth()/2;
			var py = resource.getY()+resource.getHeight()/2;

			var ix = ini.getX()+ini.getWidth()/2;
			var iy = ini.getY()+ini.getHeight()/2;

			var ex = end.getX()+end.getWidth()/2;
			var ey = end.getY()+end.getHeight()/2;

			var pointIni = Editor.Geometry.intersectionShapeAndSegment(ini, ix, iy, px, py);
			//var pointIniR = Editor.Geometry.intersectionShapeAndSegment(resource, ix, iy, px, py);
			if (!pointIni) {pointIni = new Editor.Geometry.Vector(ix,iy)}
			//if (!pointIniR) {pointIniR = new Editor.Geometry.Vector(px,py)}
			var pointIniR = new Editor.Geometry.Vector(px,py);
			var pathIni = ["M", pointIni.x, pointIni.y, "L", pointIniR.x, pointIniR.y].join(",");
			if (isInit) {
				figIni = Editor.STATE.CANVAS.path(pathIni).attr(Editor.CONFIG.CONNECTOR_ATTR);
			} else {
				figIni.attr({path: pathIni});
			}

			var pointEnd = Editor.Geometry.intersectionShapeAndSegment(end, px, py, ex, ey);
			if (!pointEnd) {pointEnd = new Editor.Geometry.Vector(ex,ey)}
			//var pointEndR = Editor.Geometry.intersectionShapeAndSegment(resource, px, py, ex, ey);
			//if (!pointEndR) {pointEndR = new Editor.Geometry.Vector(px,py)}
			var pointEndR = new Editor.Geometry.Vector(px,py);
			var pathEnd = ["M", pointEndR.x, pointEndR.y, "L", pointEnd.x, pointEnd.y].join(",");
			if (isInit) {
				figEnd = Editor.STATE.CANVAS.path(pathEnd).attr(Editor.CONFIG.CONNECTOR_ATTR);
			} else {
				figEnd.attr({path: pathEnd});
			}
			
			if (isInit) {
				figArrowPoint = Editor.STATE.CANVAS.circle(pointEnd.x, pointEnd.y, Editor.CONFIG.FIGARROWPOINT_RADIUS).attr(Editor.CONFIG.FIGARROWPOINT_ATTR);
			} else {
				figArrowPoint.remove();
				figArrowPoint = Editor.STATE.CANVAS.circle(pointEnd.x, pointEnd.y, Editor.CONFIG.FIGARROWPOINT_RADIUS).attr(Editor.CONFIG.FIGARROWPOINT_ATTR);
			}
		},
		toFrontArrowPoint: function () {
			figArrowPoint.toFront();
		},
		toFront: function () {
			resource.toFront(this);
			figArrowPoint.toFront();
		},
		moveTo: function (x, y) {
			resource.moveTo(x, y);
			this.drawLines();
		},
		translate: function (dx, dy) {
			resource._translate(dx,dy);
		},
		_resize: function (dw, dh) {
			resource._resize(dw, dh);
			this.drawLines();
		},
		resize: function (dw, dh) {
			resource.resize(dw, dh);
			this.drawLines();
		},
		figure: function () {
			return Editor.STATE.CANVAS.rect(resource.getX(), resource.getY(), resource.getWidth(), resource.getHeight(), Editor.CONFIG.PROPERTY_SHAPE_ROUNDED).
			attr(Editor.CONFIG.PROPERTY_SHAPE_ATTR);
		},
		getTextAttr: function () {
			return Editor.CONFIG.PROPERTY_TEXT_ATTR;
		},
		getShapeAttr: function () {
			return Editor.CONFIG.PROPERTY_SHAPE_ATTR;
		},
		getUuid: function () {
			return resource.getUuid();
		},
		isDeleted: function () {
			return resource.isDeleted();
		},
		getX: function () {
			return resource.getX();
		},
		getY: function () {
			return resource.getY();
		},
		getWidth: function () {
			return resource.getWidth();
		},
		getHeight: function () {
			return resource.getHeight();
		},
		toString: function () {
			return 'Property-->(' + 'uuidIni: ' + uuidIni + ' , ' + 'uuidEnd: ' + uuidEnd + ' , ' + resource.toString() + ')'
		},
		select: function () {
			resource.select(this);
		},
		unselect: function () {
			resource.unselect();	
		},
		frameResize: function () {
			return resource.frameResize();
		},
		saveIni: function (e) {
			resource.saveIni(e);
		},
		getIniPosx: function () {
			return resource.getIniPosx();
		},
		getIniPosy: function () {
			return resource.getIniPosy();
		},
		mousedown: function (e) {
			if (!Editor.Util.isDragging()) {
				resource.mousedown(e);
			}
		},
		mouseover: function () {
			if (!Editor.Util.isDragging()) {
				resource.mouseover();
			}
		},
		mouseout: function () {
			if (!Editor.Util.isDragging()) {
				resource.mouseout();
			}
		},
		click: function () {
			if (!Editor.Util.isDragging()) {
				resource.click();
			}
		},
		updateText: function () {
			resource.updateText();
		},
		getMinWidth: function () {
			return resource.getMinWidth();
		},
		getMinHeight: function () {
			return resource.getMinHeight();
		},
		showEdit: function () {
			Editor.Keys.unbind();
			Editor.STATE.SHAPETOUPDATE = this;
			$('#name').val(resource.getName());
			$('#namespacePrefix').val(resource.getNamespace().getPrefix());
			$('#namespaceUri').val(resource.getNamespace().getUri());
			$('#dialogAddResource').jqm({overlay: 40, modal: true}).jqmShow();
		},
		getDeckEdit: function () {
			return resource.getDeckEdit();
		},
		getDraggerConnector: function () {
			return resource.getDraggerConnector();
		},
		getUuidIni: function () {
			return uuidIni;
		},
		getUuidEnd: function () {
			return uuidEnd;
		},
		onmouseup: function () {
		},
		hideLines: function () {	
			figIni.attr(Editor.CONFIG.UNVISIBLE_ATTR);
			figEnd.attr(Editor.CONFIG.UNVISIBLE_ATTR);
			figArrowPoint.attr(Editor.CONFIG.UNVISIBLE_ATTR);
		},
		showLines: function () {
			figIni.attr(Editor.CONFIG.VISIBLE_ATTR);
			figEnd.attr(Editor.CONFIG.VISIBLE_ATTR);
			figArrowPoint.attr(Editor.CONFIG.VISIBLE_ATTR);
		},
		toObject: function () {
			return {
				'type': 'property',
				'uuidIni': uuidIni,
				'uuidEnd': uuidEnd,
				'resource': resource.toObject()
			}
		},
	}
}
